#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 rambla.eu
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.import os
import platform, os, sys, datetime
import unittest
import setup_environ
import json
import raws_json
from raws_json.raws_service import RawsService, Feed, Query
from raws_json.meta.service import MetaService
from raws_json.rass.service import RassService
from raws_json.meta.meta import *

class TagSearchTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.meta_service = MetaService(username = setup_environ.TEST_USERNAME, password = setup_environ.TEST_PASSWORD, server = setup_environ.TEST_SERVER)
        cls.rass_service = RassService(username = setup_environ.TEST_USERNAME, password = setup_environ.TEST_PASSWORD, server = setup_environ.TEST_RASS_SERVER)
        # delete all existing content instances
        feed = cls.meta_service.getContentList()
        mf = Feed(feed)
        for e in mf.entries:
            cls.meta_service.deleteContent(e)
        # make sure files exist on the CDN
        status = cls.rass_service.getItemHeaderFromPath("aaa.mp4")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "aaa.mp4", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("aaa.webm")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "aaa.webm", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("aaa_00.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "aaa_00.jpg", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("aaa_50.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "aaa_50.jpg", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("aaa_100.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "aaa_100.jpg", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("bbb.mp4")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "bbb.mp4", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("ccc.mp4")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "ccc.mp4", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("ddd.mp4")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "ddd.mp4", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("ggg.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "ggg.jpg", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("hhh.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "hhh.jpg", local_path = setup_environ.LOCAL_FILE)
        status = cls.rass_service.getItemHeaderFromPath("iii.jpg")
        if status != 200:
            cls.rass_service.postItem(dirpath = "", filename = "iii.jpg", local_path = setup_environ.LOCAL_FILE)

        # create content instances
        bf1 = FileObj(path = "bbb.mp4", media_type = "video", duration = 120)
        bm1 = MetaObj(meta_name = "Title", vocab = "dc", text = "Big Buck Bunny", lang = "en")
        bm2 = MetaObj(meta_name = "Creator", vocab = "dc", text = "Blender institute", lang = "en")
        bm3 = MetaObj(meta_name = "Description", vocab = "dc", text = "Big Buck Bunny (code-named Peach) is a short computer animated film by the Blender Institute", lang = "en")
        cls.big_buck_bunny_mc = MetaContent(name = "big_buck_bunny", tags = ["animated", "movie", "Blender", "python", "BigBuckBunny"], file_objs = [bf1,], meta_objs = [bm1, bm2, bm3])
        big_buck_bunny_entry = cls.meta_service.createContent(cls.big_buck_bunny_mc.to_entry())

        df1 = FileObj(path = "ddd.mp4", media_type = "video", duration = 20)
        dm1 = MetaObj(meta_name = "Title", vocab = "dc", text = "Big Buck Bunny Trailer", lang = "en")
        dm2 = MetaObj(meta_name = "Creator", vocab = "dc", text = "Blender institute", lang = "en")
        dm3 = MetaObj(meta_name = "Description", vocab = "dc", text = "Trailer of the Big Buck Bunny movie", lang = "en")
        cls.big_buck_bunny_trailer_mc = MetaContent(name = "bbb_trailer", tags = ["animated", "BigBuckBunny", "trailer"], file_objs = [df1,], meta_objs = [dm1, dm2, dm3])
        big_buck_bunny_trailer_entry = cls.meta_service.createContent(cls.big_buck_bunny_trailer_mc.to_entry())

        gf1 = FileObj(path = "ggg.jpg", media_type = "video", duration = 120)
        cls.mad_zombie_mc = MetaContent(name = "mad_zombie", tags = ["mad", "zombie", "betrail"], file_objs = [gf1,])
        mad_zombie_entry = cls.meta_service.createContent(cls.mad_zombie_mc.to_entry())

        hf1 = FileObj(path = "hhh.jpg", media_type = "video", duration = 120)
        cls.zombie_mc = MetaContent(name = "zombie", tags = ["zombie",], file_objs = [hf1,])
        zombie_entry = cls.meta_service.createContent(cls.zombie_mc.to_entry())

        f = FileObj(path = "iii.jpg", media_type = "video", duration = 120)
        cls.upper_case_zombie_mc = MetaContent(name = "upper_case_zombie", tags = ["Zombie","123456789"], file_objs = [f,])
        upper_case_zombie_entry = cls.meta_service.createContent(cls.upper_case_zombie_mc.to_entry())

       
    def test_search_tag(self):
        """ ?tag= queries """
        qry = Query()
        qry["tag"] = "BigBuckBunny"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(2, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.big_buck_bunny_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_mc)
            elif unicode(mc.name) == unicode(self.big_buck_bunny_trailer_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_trailer_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)
                
    def test_search_tag__case_sensitive(self):
        """ ?tag= queries should be case sensitive """
        # search for upper case Zombie
        qry = Query()
        qry["tag"] = "Zombie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(1, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)
        # search for lower case zombie
        qry = Query()
        qry["tag"] = "zombie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(2, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.zombie_mc.name):
                self.assertEqual(mc, self.zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)

    def test_search_tag__case_insensitive(self):
        """ ?iqtag=  """
        # search for upper case Zombie
        qry = Query()
        qry["iqtag"] = "Zombie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(3, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            elif unicode(mc.name) == unicode(self.zombie_mc.name):
                self.assertEqual(mc, self.zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)

    def test_search_tag__partial(self):
        """ ?qtag=  """
        # search for upper case Zombie
        qry = Query()
        qry["qtag"] = "ombie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(3, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            elif unicode(mc.name) == unicode(self.zombie_mc.name):
                self.assertEqual(mc, self.zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)
                
    def test_search_tag__partial_case_insensitive(self):
        """ ?iqtag= queries should be case sensitive """
        # search for upper case Zombie
        qry = Query()
        qry["iqtag"] = "OmBiE"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(3, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            elif unicode(mc.name) == unicode(self.zombie_mc.name):
                self.assertEqual(mc, self.zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)

    def test_search__multiple_tags(self):
        """ ?tag= queries with multiple tags """
        qry = Query()
        qry["tag"] = "animated,mad"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(3, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.big_buck_bunny_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_mc)
            elif unicode(mc.name) == unicode(self.big_buck_bunny_trailer_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_trailer_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)

    def test_search__multiple_qtags(self):
        """ ?qtag= queries with multiple tags """
        qry = Query()
        qry["qtag"] = "anim,mad,6789"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(4, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.big_buck_bunny_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_mc)
            elif unicode(mc.name) == unicode(self.big_buck_bunny_trailer_mc.name):
                self.assertEqual(mc, self.big_buck_bunny_trailer_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            elif unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)
                
    def test_search_qtag_and_name_multi(self):
        """ Search with both the tag + name args: ?qtag=ombie;name=*ombie """
        qry = Query()
        qry["qtag"] = "ombie"
        qry["name"] = "*ombie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(3, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            elif unicode(mc.name) == unicode(self.zombie_mc.name):
                self.assertEqual(mc, self.zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)

    def test_search_qtag_and_name_single(self):
        """ Search with both the tag + name args: ?qtag=ombie;name=_z?mbie """
        qry = Query()
        qry["qtag"] = "ombie"
        qry["name"] = "_z?mbie"
        feed = self.meta_service.getContentList(query = qry)
        mf = Feed(feed)
        self.assertEqual(2, len(mf.entries))
        for e in mf.entries:
            mc = MetaContent(entry = e)
            if unicode(mc.name) == unicode(self.upper_case_zombie_mc.name):
                self.assertEqual(mc, self.upper_case_zombie_mc)
            elif unicode(mc.name) == unicode(self.mad_zombie_mc.name):
                self.assertEqual(mc, self.mad_zombie_mc)
            else:
                assertTrue("test_search_tag(): unexpected entry name" + mc.name)



def suite():
   suite = unittest.TestSuite()
   suite.addTest(unittest.makeSuite(TagSearchTest))
   return suite

if __name__=='__main__':
    unittest.main()
